"""
Web Application

FastAPI-based web application for the AI Historical Simulation Platform
providing real-time chat interface and administrative dashboard.
"""

import logging
from pathlib import Path
from typing import Optional

try:
    from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
    from fastapi.staticfiles import StaticFiles
    from fastapi.templating import Jinja2Templates
    from fastapi.responses import HTMLResponse
    from fastapi.middleware.cors import CORSMiddleware
    FASTAPI_AVAILABLE = True
except ImportError:
    FASTAPI_AVAILABLE = False
    FastAPI = None

from .routes import setup_routes
from .websocket_manager import WebSocketManager

logger = logging.getLogger(__name__)


def create_web_app(platform) -> Optional[FastAPI]:
    """
    Create the FastAPI web application.
    
    Args:
        platform: AI Historical Simulation Platform instance
        
    Returns:
        FastAPI app instance or None if dependencies not available
    """
    if not FASTAPI_AVAILABLE:
        logger.error("FastAPI not available. Install with: pip install fastapi uvicorn jinja2 python-multipart")
        return None
    
    # Create FastAPI app
    app = FastAPI(
        title="AI Historical Simulation Platform",
        description="Interactive web interface for conversing with historical figures",
        version="1.0.0"
    )
    
    # Add CORS middleware
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["*"],
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    
    # Store platform reference
    app.state.platform = platform
    
    # Initialize WebSocket manager
    app.state.ws_manager = WebSocketManager(platform)
    
    # Setup static files
    web_dir = Path(__file__).parent
    static_dir = web_dir / "static"
    templates_dir = web_dir / "templates"
    
    # Create directories if they don't exist
    static_dir.mkdir(exist_ok=True)
    templates_dir.mkdir(exist_ok=True)
    
    # Mount static files
    app.mount("/static", StaticFiles(directory=str(static_dir)), name="static")
    
    # Setup Jinja2 templates
    templates = Jinja2Templates(directory=str(templates_dir))
    app.state.templates = templates
    
    # Setup routes
    setup_routes(app)
    
    # Create default templates if they don't exist
    _create_default_templates(templates_dir)
    _create_default_static_files(static_dir)
    
    logger.info("Web application created successfully")
    return app


def _create_default_templates(templates_dir: Path) -> None:
    """Create default HTML templates."""
    
    # Main layout template
    layout_template = templates_dir / "layout.html"
    if not layout_template.exists():
        layout_content = '''<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}AI Historical Simulation Platform{% endblock %}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/style.css" rel="stylesheet">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
        <div class="container">
            <a class="navbar-brand" href="/">🏛️ Historical Simulation Platform</a>
            <div class="navbar-nav ms-auto">
                <a class="nav-link" href="/">Chat</a>
                <a class="nav-link" href="/dashboard">Dashboard</a>
                <a class="nav-link" href="/scenarios">Scenarios</a>
            </div>
        </div>
    </nav>
    
    <main class="container mt-4">
        {% block content %}{% endblock %}
    </main>
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/static/script.js"></script>
    {% block scripts %}{% endblock %}
</body>
</html>'''
        
        with open(layout_template, 'w') as f:
            f.write(layout_content)
    
    # Chat interface template
    chat_template = templates_dir / "chat.html"
    if not chat_template.exists():
        chat_content = '''{% extends "layout.html" %}

{% block title %}Chat - AI Historical Simulation Platform{% endblock %}

{% block content %}
<div class="row">
    <div class="col-md-3">
        <div class="card">
            <div class="card-header">
                <h5>Historical Figures</h5>
            </div>
            <div class="card-body">
                <div id="figures-list">
                    <!-- Figures will be loaded here -->
                </div>
            </div>
        </div>
    </div>
    
    <div class="col-md-9">
        <div class="card">
            <div class="card-header d-flex justify-content-between">
                <h5 id="current-figure">Select a Historical Figure</h5>
                <button class="btn btn-sm btn-outline-primary" onclick="clearChat()">Clear Chat</button>
            </div>
            <div class="card-body">
                <div id="chat-messages" style="height: 400px; overflow-y: scroll; border: 1px solid #dee2e6; padding: 15px; border-radius: 5px;">
                    <div class="text-muted text-center">
                        <p>Welcome to the AI Historical Simulation Platform!</p>
                        <p>Select a historical figure to start a conversation.</p>
                    </div>
                </div>
                
                <div class="mt-3">
                    <div class="input-group">
                        <input type="text" id="message-input" class="form-control" 
                               placeholder="Type your message..." disabled>
                        <button class="btn btn-primary" id="send-button" onclick="sendMessage()" disabled>
                            Send
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div id="connection-status" class="position-fixed bottom-0 end-0 m-3">
    <div class="badge bg-secondary">Connecting...</div>
</div>
{% endblock %}

{% block scripts %}
<script>
    let ws = null;
    let currentFigure = null;
    
    function initWebSocket() {
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        ws = new WebSocket(`${protocol}//${window.location.host}/ws`);
        
        ws.onopen = function() {
            document.getElementById('connection-status').innerHTML = 
                '<div class="badge bg-success">Connected</div>';
            loadFigures();
        };
        
        ws.onmessage = function(event) {
            const data = JSON.parse(event.data);
            handleWebSocketMessage(data);
        };
        
        ws.onclose = function() {
            document.getElementById('connection-status').innerHTML = 
                '<div class="badge bg-danger">Disconnected</div>';
        };
    }
    
    function handleWebSocketMessage(data) {
        if (data.type === 'figures_list') {
            displayFigures(data.figures);
        } else if (data.type === 'chat_response') {
            displayMessage(data.figure, data.response);
        } else if (data.type === 'error') {
            displayError(data.message);
        }
    }
    
    function loadFigures() {
        ws.send(JSON.stringify({type: 'get_figures'}));
    }
    
    function displayFigures(figures) {
        const figuresList = document.getElementById('figures-list');
        figuresList.innerHTML = '';
        
        figures.forEach(figure => {
            const button = document.createElement('button');
            button.className = 'btn btn-outline-primary btn-sm mb-2 w-100';
            button.textContent = figure;
            button.onclick = () => selectFigure(figure);
            figuresList.appendChild(button);
        });
    }
    
    function selectFigure(figureName) {
        currentFigure = figureName;
        document.getElementById('current-figure').textContent = `Chatting with ${figureName}`;
        document.getElementById('message-input').disabled = false;
        document.getElementById('send-button').disabled = false;
        
        // Clear chat and show welcome message
        const chatMessages = document.getElementById('chat-messages');
        chatMessages.innerHTML = `
            <div class="alert alert-info">
                You are now chatting with <strong>${figureName}</strong>. 
                Ask them about their life, thoughts, or historical events!
            </div>
        `;
        
        // Focus on input
        document.getElementById('message-input').focus();
    }
    
    function sendMessage() {
        const input = document.getElementById('message-input');
        const message = input.value.trim();
        
        if (!message || !currentFigure) return;
        
        // Display user message
        displayMessage('You', message, true);
        
        // Send to server
        ws.send(JSON.stringify({
            type: 'chat_message',
            figure: currentFigure,
            message: message
        }));
        
        input.value = '';
    }
    
    function displayMessage(sender, message, isUser = false) {
        const chatMessages = document.getElementById('chat-messages');
        const messageDiv = document.createElement('div');
        messageDiv.className = `mb-3 ${isUser ? 'text-end' : ''}`;
        
        const badgeClass = isUser ? 'bg-primary' : 'bg-success';
        messageDiv.innerHTML = `
            <div class="d-inline-block p-2 rounded ${isUser ? 'bg-light' : 'bg-light'}">
                <strong class="badge ${badgeClass}">${sender}</strong>
                <div class="mt-1">${message}</div>
            </div>
        `;
        
        chatMessages.appendChild(messageDiv);
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }
    
    function displayError(message) {
        const chatMessages = document.getElementById('chat-messages');
        const errorDiv = document.createElement('div');
        errorDiv.className = 'alert alert-danger mb-3';
        errorDiv.textContent = `Error: ${message}`;
        chatMessages.appendChild(errorDiv);
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }
    
    function clearChat() {
        document.getElementById('chat-messages').innerHTML = 
            '<div class="text-muted text-center"><p>Chat cleared.</p></div>';
    }
    
    // Handle Enter key in message input
    document.addEventListener('DOMContentLoaded', function() {
        document.getElementById('message-input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                sendMessage();
            }
        });
        
        // Initialize WebSocket connection
        initWebSocket();
    });
</script>
{% endblock %}'''
        
        with open(chat_template, 'w') as f:
            f.write(chat_content)
    
    # Dashboard template
    dashboard_template = templates_dir / "dashboard.html"
    if not dashboard_template.exists():
        dashboard_content = '''{% extends "layout.html" %}

{% block title %}Dashboard - AI Historical Simulation Platform{% endblock %}

{% block content %}
<div class="row">
    <div class="col-md-12">
        <h2>System Dashboard</h2>
    </div>
</div>

<div class="row">
    <div class="col-md-3">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">Active Sessions</h5>
                <h2 class="text-primary" id="active-sessions">-</h2>
            </div>
        </div>
    </div>
    
    <div class="col-md-3">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">Total Conversations</h5>
                <h2 class="text-success" id="total-conversations">-</h2>
            </div>
        </div>
    </div>
    
    <div class="col-md-3">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">Available Figures</h5>
                <h2 class="text-info" id="available-figures">-</h2>
            </div>
        </div>
    </div>
    
    <div class="col-md-3">
        <div class="card text-center">
            <div class="card-body">
                <h5 class="card-title">System Health</h5>
                <h2 class="text-warning" id="system-health">-</h2>
            </div>
        </div>
    </div>
</div>

<div class="row mt-4">
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h5>Performance Metrics</h5>
            </div>
            <div class="card-body">
                <div id="performance-metrics">
                    Loading metrics...
                </div>
            </div>
        </div>
    </div>
    
    <div class="col-md-6">
        <div class="card">
            <div class="card-header">
                <h5>System Status</h5>
            </div>
            <div class="card-body">
                <div id="system-status">
                    Loading status...
                </div>
            </div>
        </div>
    </div>
</div>

<div class="row mt-4">
    <div class="col-md-12">
        <div class="card">
            <div class="card-header">
                <h5>Recent Activity</h5>
            </div>
            <div class="card-body">
                <div id="recent-activity">
                    Loading activity...
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block scripts %}
<script>
    function loadDashboardData() {
        // Load performance metrics
        fetch('/api/metrics')
            .then(response => response.json())
            .then(data => {
                updateMetrics(data);
            })
            .catch(error => console.error('Error loading metrics:', error));
        
        // Load system health
        fetch('/api/health')
            .then(response => response.json())
            .then(data => {
                updateSystemHealth(data);
            })
            .catch(error => console.error('Error loading health:', error));
    }
    
    function updateMetrics(data) {
        document.getElementById('active-sessions').textContent = data.active_sessions || 0;
        document.getElementById('total-conversations').textContent = data.total_conversations || 0;
        document.getElementById('available-figures').textContent = data.loaded_figures || 0;
        
        // Update performance metrics table
        const metricsHtml = `
            <table class="table table-sm">
                <tr><td>Average Response Time</td><td>${(data.avg_response_time || 0).toFixed(2)}s</td></tr>
                <tr><td>Total Responses</td><td>${data.total_responses_generated || 0}</td></tr>
                <tr><td>Memory Operations</td><td>${data.memory_operations || 0}</td></tr>
                <tr><td>Uptime</td><td>${Math.round(data.uptime_seconds || 0)}s</td></tr>
            </table>
        `;
        document.getElementById('performance-metrics').innerHTML = metricsHtml;
    }
    
    function updateSystemHealth(data) {
        const isHealthy = data.is_initialized && data.hdc_operations_available;
        document.getElementById('system-health').textContent = isHealthy ? '✓' : '✗';
        document.getElementById('system-health').className = isHealthy ? 'text-success' : 'text-danger';
        
        // Update system status
        const statusHtml = `
            <table class="table table-sm">
                <tr><td>Initialized</td><td>${data.is_initialized ? '✓' : '✗'}</td></tr>
                <tr><td>HDC Operations</td><td>${data.hdc_operations_available ? '✓' : '✗'}</td></tr>
                <tr><td>Memory Usage</td><td>${data.memory_usage || 'N/A'}</td></tr>
                <tr><td>Consciousness States</td><td>${data.consciousness_states || 0}</td></tr>
            </table>
        `;
        document.getElementById('system-status').innerHTML = statusHtml;
    }
    
    // Auto-refresh dashboard every 10 seconds
    document.addEventListener('DOMContentLoaded', function() {
        loadDashboardData();
        setInterval(loadDashboardData, 10000);
    });
</script>
{% endblock %}'''
        
        with open(dashboard_template, 'w') as f:
            f.write(dashboard_content)


def _create_default_static_files(static_dir: Path) -> None:
    """Create default static files."""
    
    # CSS file
    css_file = static_dir / "style.css"
    if not css_file.exists():
        css_content = '''
/* Custom styles for AI Historical Simulation Platform */

body {
    background-color: #f8f9fa;
}

.card {
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
    border: 1px solid rgba(0, 0, 0, 0.125);
}

.navbar-brand {
    font-weight: bold;
}

#chat-messages {
    background-color: white;
}

#chat-messages .alert {
    margin-bottom: 0.5rem;
}

.message-bubble {
    max-width: 70%;
    word-wrap: break-word;
}

.user-message {
    margin-left: auto;
    background-color: #007bff;
    color: white;
}

.figure-message {
    margin-right: auto;
    background-color: #f8f9fa;
    border: 1px solid #dee2e6;
}

#connection-status {
    z-index: 1000;
}

.btn:focus {
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

.table td {
    vertical-align: middle;
}

.dashboard-metric {
    font-size: 2rem;
    font-weight: bold;
}
'''
        
        with open(css_file, 'w') as f:
            f.write(css_content)
    
    # JavaScript file
    js_file = static_dir / "script.js"
    if not js_file.exists():
        js_content = '''
// Common JavaScript functions for AI Historical Simulation Platform

function showToast(message, type = 'info') {
    // Simple toast notification
    const toastHtml = `
        <div class="toast align-items-center text-white bg-${type} border-0" role="alert">
            <div class="d-flex">
                <div class="toast-body">${message}</div>
                <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
            </div>
        </div>
    `;
    
    // Create toast container if it doesn't exist
    let toastContainer = document.getElementById('toast-container');
    if (!toastContainer) {
        toastContainer = document.createElement('div');
        toastContainer.id = 'toast-container';
        toastContainer.className = 'toast-container position-fixed bottom-0 end-0 p-3';
        document.body.appendChild(toastContainer);
    }
    
    toastContainer.insertAdjacentHTML('beforeend', toastHtml);
    
    // Show the toast
    const toastElement = toastContainer.lastElementChild;
    const toast = new bootstrap.Toast(toastElement);
    toast.show();
    
    // Remove toast element after it's hidden
    toastElement.addEventListener('hidden.bs.toast', function() {
        toastElement.remove();
    });
}

function formatTimestamp(timestamp) {
    const date = new Date(timestamp);
    return date.toLocaleString();
}

function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

// Loading indicator functions
function showLoading(elementId) {
    const element = document.getElementById(elementId);
    if (element) {
        element.innerHTML = '<div class="spinner-border spinner-border-sm" role="status"><span class="visually-hidden">Loading...</span></div>';
    }
}

function hideLoading(elementId, content) {
    const element = document.getElementById(elementId);
    if (element) {
        element.innerHTML = content;
    }
}
'''
        
        with open(js_file, 'w') as f:
            f.write(js_content)